package rock.remoting.handler;

import lombok.extern.slf4j.Slf4j;
import rock.common.factory.SingletonFactory;
import rock.exception.RpcException;
import rock.provider.ServiceProvider;
import rock.provider.impl.ZkServiceProviderImpl;
import rock.remoting.dto.RpcRequest;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

@Slf4j
public class RpcRequestHandler {
    private final ServiceProvider serviceProvider;

    public RpcRequestHandler() {
        this.serviceProvider = SingletonFactory.getInstance(ZkServiceProviderImpl.class);
    }

    /**
     * 处理rpc请求
     * @param request rpc 请求
     * @return
     */
    public Object handle(RpcRequest request) {
        Object service = serviceProvider.get(request.getRpcServiceName());
        return invoke(request, service);
    }

    private Object invoke(RpcRequest request, Object service) {
        Object result;
        try {
            Method method = service.getClass().getMethod(request.getMethodName(), request.getParamTypes());
            result = method.invoke(service, request.getParameters());
            log.info("service for: {[]} success invoke method:[{}]", request.getInterfaceName(), request.getMethodName());
        } catch (NoSuchMethodException | IllegalArgumentException
                | InvocationTargetException | IllegalAccessException e) {
            throw new RpcException(e.getMessage(), e);
        }

        return result;
    }
}
